/*
 * 版权所有 (C) 2015 知启蒙(ZHIQIM) 保留所有权利。[遇见知启蒙，邂逅框架梦]
 * 
 * https://zhiqim.org/project/zhiqim_framework/zhiqim_kernel.htm
 *
 * Zhiqim Kernel is licensed under Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of Mulan PSL v2 at:
 *          http://license.coscl.org.cn/MulanPSL2
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PSL v2 for more details.
 */
package org.zhiqim.kernel.util;

import org.zhiqim.kernel.annotation.AnAlias;

/**
 * 基本类型相关工具类
 *
 * @version v1.0.0 @author zouzhigang 2014-3-21 新建与整理
 */
@AnAlias("Types")
public class Types
{
    /** 把八种基本类型转为对象类型 */
    public static Class<?> toObjectClass(Class<?> cls)
    {
        if (cls == int.class)
            return Integer.class;
        else if (cls == long.class)
            return Long.class;
        else if (cls == boolean.class)
            return Boolean.class;
        else if (cls == byte.class)
            return Byte.class;
        else if (cls == short.class)
            return Short.class;
        else if (cls == char.class)
            return Character.class;
        else if (cls == float.class)
            return Float.class;
        else if (cls == double.class)
            return Double.class;
        else
            return cls;
    }
    
    /************************************************************/
    //类判断
    /************************************************************/
    
    /** 是否八种基本类型，支持byte/short/int/long/float/double/boolean/char和对应的类Byte/Short */
    public static boolean isPrimitive(Class<?> cls)
    {
        return cls != null && (isNumber(cls) || isBoolean(cls) || isChar(cls));
    }
    
    /** 是否八种基本原型基本类型，仅支持byte/short/int/long/float/double/boolean/char */
    public static boolean isPrimitiveBase(Class<?> cls)
    {
        return cls == int.class  || cls == long.class    || cls == short.class || cls == byte.class || 
               cls == char.class || cls == boolean.class || cls == float.class || cls == double.class;
    }
    
    /** 是否数值型(整数/小数)，支持byte/short/int/long/float/double */
    public static boolean isNumber(Class<?> cls)
    {
        return isInteger(cls) || isDecimal(cls);
    }
    
    /** 是否整数，区别于isInt，支持byte/short/int/long */
    public static boolean isInteger(Class<?> cls)
    {
        return cls == int.class || cls == Integer.class || cls == long.class || cls == Long.class || 
               cls == byte.class || cls == Byte.class || cls == short.class || cls == Short.class;
    }
    
    /** 是否小数，float和double */
    public static boolean isDecimal(Class<?> cls)
    {
        return cls == float.class || cls == Float.class || cls == double.class || cls == Double.class;
    }
    
    /** 是否int，int/Integer */
    public static boolean isInt(Class<?> cls)
    {
        return cls == int.class || cls == Integer.class;
    }
    
    /** 是否long，long/Long */
    public static boolean isLong(Class<?> cls)
    {
        return cls == long.class || cls == Long.class;
    }
    
    /** 是否short，short/Short */
    public static boolean isShort(Class<?> cls)
    {
        return cls == short.class || cls == Short.class;
    }
    
    /** 是否char，char/Character */
    public static boolean isChar(Class<?> cls)
    {
        return cls == char.class || cls == Character.class;
    }
    
    /** 是否byte，byte/Byte */
    public static boolean isByte(Class<?> cls)
    {
        return cls == byte.class || cls == Byte.class;
    }
    
    /** 是否float，float/Float */
    public static boolean isFloat(Class<?> cls)
    {
        return cls == float.class || cls == Float.class;
    }
    
    /** 是否double，double/Double */
    public static boolean isDouble(Class<?> cls)
    {
        return cls == double.class || cls == Double.class;
    }
    
    /** 是否boolean，boolean/Boolean */
    public static boolean isBoolean(Class<?> clazz)
    {
        return clazz == boolean.class || clazz == Boolean.class;
    }
    
    /************************************************************/
    //对象判断
    /************************************************************/
    
    /** 是否单一类型，支持null/byte/short/int/long/float/double/boolean/char/String */
    public static boolean isSingle(Object obj)
    {
        return (obj == null) || isInt(obj) || isLong(obj) || isBoolean(obj) || isByte(obj) || 
                isShort(obj) || isChar(obj) || isFloat(obj) || isDouble(obj) || isString(obj);
    }
    
    /** 是否八种基本类型，支持byte/short/int/long/float/double/boolean/char */
    public static boolean isPrimitive(Object obj)
    {
        return obj != null && 
              (isInt(obj) || isLong(obj) || isBoolean(obj) || isByte(obj) || 
               isShort(obj) || isChar(obj) || isFloat(obj) || isDouble(obj));
    }
    
    /** 是否数值型(整数/小数)，支持byte/short/int/long/float/double */
    public static boolean isNumber(Object obj)
    {
        return isInteger(obj) || isDecimal(obj);
    }
    
    /** 是否整数，区别于isInt，支持byte/short/int/long */
    public static boolean isInteger(Object obj)
    {
        return isInt(obj) || isLong(obj) || isByte(obj) || isShort(obj);
    }
    
    /** 是否小数，支持float/double */
    public static boolean isDecimal(Object obj)
    {
        return isFloat(obj) || isDouble(obj);
    }

    /** 是否为null */
    public static boolean isNull(Object obj)
    {
        return (obj == null);
    }
    
    /** 是否为字符串 */
    public static boolean isString(Object obj)
    {
        return (obj == null)?false:(obj instanceof String);
    }
    
    /** 是否为int/Integer */
    public static boolean isInt(Object obj)
    {
        return (obj == null)?false:(obj instanceof Integer);
    }
    
    /** 是否为long/Long */
    public static boolean isLong(Object obj)
    {
        return (obj == null)?false:(obj instanceof Long);
    }
    
    /** 是否为short/Short */
    public static boolean isShort(Object obj)
    {
        return (obj == null)?false:(obj instanceof Short);
    }
    
    /** 是否为byte/Byte */
    public static boolean isByte(Object obj)
    {
        return (obj == null)?false:(obj instanceof Byte);
    }

    /** 是否为char/Character */
    public static boolean isChar(Object obj)
    {
        return (obj == null)?false:(obj instanceof Character);
    }
    
    /** 是否为boolean/Boolean */
    public static boolean isBoolean(Object obj)
    {
        return (obj == null)?false:(obj instanceof Boolean);
    }

    /** 是否为float/Float */
    public static boolean isFloat(Object obj)
    {
        return (obj == null)?false:(obj instanceof Float);
    }
    
    /** 是否为double/Double */
    public static boolean isDouble(Object obj)
    {
        return (obj == null)?false:(obj instanceof Double);
    }
    
    /************************************************************/
    //对象数组判断
    /************************************************************/

    /** 是否为数组 */
    public static boolean isArray(Object obj)
    {
        return (obj == null)?false:obj.getClass().isArray();
    }
    
    /** 是否为数组 */
    public static boolean isArray(Class<?> clazz)
    {
        return (clazz == null)?false:clazz.isArray();
    }

    /** 是否8种基本类型对象数组，支持byte[]/short[]/int[]/long[]/float[]/double[]/boolean[]/char[]
     *  这里只判断类int[],不去判断Integer[]，因为Integer[]可转化为Object[]，而int[]不行 */
    public static boolean isPrimitiveArray(Class<?> cls)
    {
        return (cls != null) &&
               (cls == int[].class || cls == long[].class || cls == boolean[].class || cls == byte[].class || 
                cls == char[].class || cls == short[].class || cls == float[].class || cls == double[].class);
    }
    
    /**
     * 是否8种基本类型对象数组，支持byte/short/int/long/float/double/boolean/char
     * 
     * 这里只判断类int[],不去判断Integer[]，因为Integer[]可转化为Object[]，而int[]不行
     * 
     * @param obj 对象
     * @return =true/=false
     */
    public static boolean isPrimitiveArray(Object obj)
    {
        return (obj == null)?false:isPrimitiveArray(obj.getClass());
    }
    
    /** 是否为int[]，注意Integer[]不是int[] */
    public static boolean isIntArray(Object obj)
    {
        return (obj == null)?false:obj.getClass() == int[].class;
    }
    
    /** 是否为long[]，注意Long[]不是long[] */
    public static boolean isLongArray(Object obj)
    {
        return (obj == null)?false:obj.getClass() == long[].class;
    }
    
    /** 是否为short[]，注意Short[]不是short[] */
    public static boolean isShortArray(Object obj)
    {
        return (obj == null)?false:obj.getClass() == short[].class;
    }
    
    /** 是否为byte[]，注意Byte[]不是byte[] */
    public static boolean isByteArray(Object obj)
    {
        return (obj == null)?false:obj.getClass() == byte[].class;
    }
    
    /** 是否为char[]，注意Character[]不是char[] */
    public static boolean isCharArray(Object obj)
    {
        return (obj == null)?false:obj.getClass() == char[].class;
    }
    
    /** 是否为float[]，注意Float[]不是float[] */
    public static boolean isFloatArray(Object obj)
    {
        return (obj == null)?false:obj.getClass() == float[].class;
    }
    
    /** 是否为double[]，注意Double[]不是double[] */
    public static boolean isDoubleArray(Object obj)
    {
        return (obj == null)?false:obj.getClass() == double[].class;
    }
    
    /** 是否为boolean[]，注意Boolean[]不是boolean[] */
    public static boolean isBooleanArray(Object obj)
    {
        return (obj == null)?false:obj.getClass() == boolean[].class;
    }
}
